# encoding:utf-8
from mod_python import apache
import urllib, StringIO, socket, select

max_idling = 30

def parse_url(url):
    import urlparse
    o = urlparse.urlparse(url)
    host = o.netloc
    port = o.port
    if not port:
        port = 80
    if host.find(':') != -1:
        host = host[:host.find[':']]

    return (host, port, url[url.find(host)+len(host):])


def ReceiveHeaders(s):
    headers = ''
    iw = [s,]
    ow = []
    count = 0
    while 1:
        rs, ws, es = select.select(iw, ow, iw, 1)
        if es:
            break
        if rs:
            count = 0
            b = s.recv(1)
            headers += b
            if headers.rfind('\r\n\r\n', -4) != -1:
                break
        count += 1
        if count > 60:
            break

    return headers


def socket_handler2(req):
    s = None
    try:
        out = StringIO.StringIO(req.read())
        req_line = out.readline().strip()
        orig_path = req_line.split()[1]
        host, port, url = parse_url(orig_path)
 
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((host, port))
        s.send(req_line.replace(orig_path, url) + '\r\n')
        
        line = out.readline().strip()
        while line:
            sep = line.find(':')
            if line[:sep] == 'Connection':
                s.send('Connection: close\r\n')
            elif line[:sep] == 'Proxy-Connection':
                pass
            else:
                s.send(line + '\r\n')
            line = out.readline().strip()

        s.send('\r\n')
        s.send(out.read())
        
        iw = [s,]
        ow = []
        count = 0
        while 1:
            count += 1
            rd, wr, ex = select.select(iw, ow, iw, 1)
            if ex: break
            for fd in rd:
                data = fd.recv(4096)
                if data:
                    req.write(data)
                    count = 0
                else:
                    break
            if count == max_idling: break
    except:
        pass
    finally:
        if s:
            s.close()
    return apache.OK


#def socket_handler(req):
#    ret = apache.OK
#    s = None
#    try:
#        out = StringIO.StringIO(req.read())
#        req_line = out.readline().strip()
#        orig_path = req_line.split()[1]
#        host, port, url = parse_url(orig_path)
# 
#        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#        s.connect((host, port))
#        s.send(req_line.replace(orig_path, url) + '\r\n')
#        offset = len(req_line) + 2
#        
#        line = out.readline().strip()
#        while line:
#            sep = line.find(':')
#            if line[:sep] == 'Connection':
#                s.send('Connection: close\r\n')
#            elif line[:sep] == 'Proxy-Connection':
#                pass
#            else:
#                s.send(line + '\r\n')
#            line = out.readline().strip()
#
#        s.send('\r\n')
#        s.send(out.read())
#        
#        out = StringIO.StringIO()
#        iw = [s,]
#        ow = []
#        count = 0
#        while 1:
#            count += 1
#            rd, wr, ex = select.select(iw, ow, iw, 3)
#            if ex: break
#            for fd in rd:
#                data = fd.recv(4096)
#                if data:
#                    out.write(data)
#                    count = 0
#                else:
#                    break
#            if count == max_idling: break
#       
#        data = out.getvalue()
#        out = StringIO.StringIO(data)
#        ret = int(out.readline()[10:13])
#        hs = "Not empty"
#        while hs:
#            hs = out.readline().strip()
#            if not hs:
#                break
#            com = hs.find(':')
#            header = hs[:com]
#            value = hs[com+1:]
#            #req.write('%s:%s\r\n' % (header, value))
#            if header == 'Content-Type':
#                req.content_type = value
#            else:
#                req.headers_out[header] = value.strip()
#   
#        req.write(out.read())
#    except:
#        pass
#    finally:
#        if s:
#            s.close()
#    return ret


def handler(req):
#    req.handler = 'mod_python'
#    req.add_handler('PythonConnectionHandler', 'py_proxy')
#    return apache.OK

    if req.method == 'POST':
        return socket_handler2(req)
        
    if req.method == 'GET':
        req.content_type = 'text/html; charset=utf-8'
        req.write(\
'''
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>url_proxy (on mod_python) is working now.</title>
    </head>
    <body>
        <table width="800" border="0" align="center">
            <tr><td align="center"><hr></td></tr>
            <tr><td align="center">
                <b><h1>url_proxy (on mod_python) is working now.</h1></b>
            </td></tr>
            <tr><td align="center"><hr></td></tr>

            <tr><td align="center">
                url_proxy (on mod_python) is an open source HTTP proxy running on mod_python. Now it only support http not https.
            </td></tr>
            <tr><td align="center"><hr></td></tr>
        </table>
    </body>
</html>
''')
        return apache.OK
